import { UNIT_LIST, DYNAMIC_COMPONENT_KEY } from './enums'
import { ObjToArrOptions } from './type'
import _ from 'lodash'

export function handleDynamicProps(el: Record<string, any>, data: any) {
  const { props, name } = el
  // console.log(props, name)
  const key = DYNAMIC_COMPONENT_KEY[name]
  let value = ''

  if (key) value = _.get(data, props.dataKey, '')
  if (name === 'k-text' && props.text) {
    return value + props.text
  }
  return value
}
export function getDeepObjAttrs<O extends object, D>(obj: O, key: string, defaultValue?: D) {
  if (!obj) return defaultValue
  return _.get(obj, key, defaultValue)
}
export function padZero(num: number | string) {
  return String(num).padStart(2, '0')
}

export function objToArr<T extends object, V>(obj: T, options?: ObjToArrOptions) {
  return Object.entries(obj).map(([k, v]) => {
    const config = {
      labelKey: 'label',
      valueKey: 'value',
      ...options,
    }

    return {
      [config.labelKey]: v,
      [config.valueKey]: config.transform ? config.transform(k) : (k as V),
    }
  })
}

// Option数组转对象
export function arrToMaps<T extends Record<string, any>>(
  arr: T[],
  valueKey = 'value',
  labelKey = 'label',
): Record<string, string> {
  if (!Array.isArray(arr)) return arr
  return arr.reduce((prv: Record<string, string>, cur: Record<string, string>) => {
    prv[cur[valueKey]] = cur[labelKey]
    return prv
  }, {})
}

export function objectToKeyValueArray(
  obj: Record<string, any>,
): Array<{ key: string; value: any }> {
  return Object.entries(obj).map(([key, value]) => ({
    key,
    value,
  }))
}

// 提取数字，去除单位
export function extractNumberFromValue(val: string | number) {
  if (!val && val !== 0) return ''

  const value = String(val)
  // 检查是否包含单位
  for (const unit of UNIT_LIST) {
    if (value.endsWith(unit.value)) {
      return value.replace(unit.value, '')
    }
  }

  // 如果没有找到单位，则返回原值
  return value
}

// 从字符串中提取数字
export function extractNumber(str: string) {
  if (!str) return 0
  if (typeof str === 'number') return str
  // 使用正则表达式匹配数字部分
  const match = str.match(/^(\d+(\.\d+)?)/)
  if (match && match[1]) {
    return parseFloat(match[1])
  }
  return 0
}

/**
 * 验证十进制数字
 */
export function isNumber(value: string) {
  return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(String(value))
}

// 添加单位，如果有rpx，%，px等单位结尾或者值为auto，直接返回，否则加上rpx单位结尾
export function addUnit(value = 'auto', unit = 'px') {
  // 用uView内置验证规则中的number判断是否为数值
  return isNumber(value) ? `${value}${unit}` : value
}
// 获取颜色值
export function getColor(str: string) {
  if (!str) return ''

  // 匹配十六进制颜色 (#fff, #ffffff)
  const hexMatch = str.match(/#([0-9a-fA-F]{3,8})\b/)
  if (hexMatch) return hexMatch[0]

  // 匹配rgb/rgba颜色
  const rgbMatch = str.match(/rgba?\s*\([^)]+\)/)
  if (rgbMatch) return rgbMatch[0]

  // 匹配hsl/hsla颜色
  const hslMatch = str.match(/hsla?\s*\([^)]+\)/)
  if (hslMatch) return hslMatch[0]
  return str
}

export function style2str(style: Record<string, any>, decollator = ';') {
  return Object.entries(style)
    .map(([key, value]) => `${key}: ${value}`)
    .join(decollator)
}

// 判断对象是否为空
export function isNull<O extends object>(obj: O) {
  return Object.keys(obj).length <= 0
}

// 过滤对象中值为空的属性
export function filterNullProps<O extends object>(obj: O) {
  return Object.entries(obj).reduce(
    (acc, [key, value]) => {
      const isNull = value === '' || value === undefined || value == null
      return isNull ? acc : { ...acc, [key]: value }
    },
    {} as Record<string, any>,
  )
}

export const isMobile = () => {
  const userAgent = navigator.userAgent.toLowerCase()
  return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)
}

/**
 * 将对象转换为树形下拉菜单数据
 * @param {Object} obj - 要转换的对象
 * @param {string} parentKey - 父级键名（递归用）
 * @return {Array} - 树形菜单数据
 */
export function objectToTreeOptions(obj: Record<string, any>, parentKey = '') {
  const result = []

  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const currentKey = parentKey ? `${parentKey}.${key}` : key
      const item: Record<string, any> = {
        value: currentKey,
        label: key,
      }

      // 如果值是对象且不是数组，则递归处理
      if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
        item.children = objectToTreeOptions(obj[key], currentKey)
      }

      result.push(item)
    }
  }

  return result
}
